package com.example.onlineanswer.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.onlineanswer.mapper.AnswerMapper;
import com.example.onlineanswer.mapper.ContestMapper;
import com.example.onlineanswer.mapper.QuestionMapper;
import com.example.onlineanswer.model.entity.Answer;
import com.example.onlineanswer.model.entity.Contest;
import com.example.onlineanswer.model.entity.Question;
import com.example.onlineanswer.model.vo.AnswerStatisticsVO;
import com.example.onlineanswer.model.vo.QuestionOptionVO;
import com.example.onlineanswer.model.vo.QuestionVO;
import com.example.onlineanswer.model.vo.UserAnswerVO;
import com.example.onlineanswer.service.AnswerService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 答题服务实现类
 */
@Service
@RequiredArgsConstructor
public class AnswerServiceImpl extends ServiceImpl<AnswerMapper, Answer> implements AnswerService {

    private final AnswerMapper answerMapper;
    private final QuestionMapper questionMapper;
    private final ContestMapper contestMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submitAnswer(Answer answer) {
        // 获取参赛记录，确认用户ID
        Long participationId = answer.getParticipationId();
        if (participationId == null) {
            return false;
        }
        
        // 检查用户是否已回答过该题目
        if (hasAnsweredByParticipationAndQuestion(participationId, answer.getQuestionId())) {
            return false;
        }
        
        // 设置答题时间
        answer.setCreateTime(LocalDateTime.now());
        
        // 判断答案是否正确
        QuestionVO questionVO = questionMapper.getQuestionDetailById(answer.getQuestionId());
        if (questionVO != null) {
            // 判断答案是否正确
            // 这里简化实现，实际中可能需要根据题目类型进行不同的判断
            // 例如单选题和多选题的判断逻辑不同
            boolean isCorrect = checkAnswerCorrect(questionVO, answer.getContent());
            answer.setIsCorrect(isCorrect);
            
            // 计算得分（根据是否正确和用时计算）
            if (isCorrect) {
                // 简单计分逻辑：正确得分，可以根据难度和用时调整
                answer.setScore(questionVO.getScore());
            } else {
                answer.setScore(0);
            }
        } else {
            // 题目不存在，设置为错误
            answer.setIsCorrect(false);
            answer.setScore(0);
        }
        
        // 默认状态为未审核（如果有需要审核的题目类型）
        answer.setStatus(0);
        
        // 保存答题记录
        return save(answer);
    }
    
    /**
     * 检查答案是否正确
     * 
     * @param question 题目
     * @param userAnswer 用户答案
     * @return 是否正确
     */
    private boolean checkAnswerCorrect(QuestionVO question, String userAnswer) {
        // 如果是选择题，从选项中判断正确性
        if (question.getOptions() != null && !question.getOptions().isEmpty()) {
            // 单选题情况
            // 获取正确选项的序号
            List<String> correctOptions = question.getOptions().stream()
                .filter(option -> option.getCorrect() != null && option.getCorrect())
                .map(option -> option.getOptionOrder())
                .collect(Collectors.toList());
            
            // 判断用户答案是否匹配正确选项
            return correctOptions.contains(userAnswer);
        }
        
        // 判断题
        if (question.getTypeId() == 3 && question.getCorrectAnswer() != null) {
            return userAnswer.equals(question.getCorrectAnswer().toString());
        }
        
        // 填空题和简答题（需要更复杂的匹配逻辑，这里简化处理）
        if ((question.getTypeId() == 4 || question.getTypeId() == 5) && 
            question.getReferAnswer() != null && !question.getReferAnswer().isEmpty()) {
            // 简单匹配，实际中可能需要模糊匹配或人工审核
            return userAnswer.trim().equalsIgnoreCase(question.getReferAnswer().trim());
        }
        
        // 无法判断
        return false;
    }

    @Override
    public List<UserAnswerVO> getUserAnswersByContestId(Long userId, Long contestId) {
        return answerMapper.getUserAnswersByContestId(userId, contestId);
    }

    @Override
    public IPage<UserAnswerVO> pageContestAnswers(Page<UserAnswerVO> page, Long contestId, Long questionId, Long userId, Boolean isCorrect) {
        return answerMapper.pageContestAnswers(page, contestId, questionId, userId, isCorrect);
    }

    @Override
    public AnswerStatisticsVO getQuestionAnswerStatistics(Long contestId, Long questionId) {
        return answerMapper.getQuestionAnswerStatistics(contestId, questionId);
    }

    @Override
    public boolean hasUserAnswered(Long userId, Long participationId, Long questionId) {
        // 查询是否已存在记录
        LambdaQueryWrapper<Answer> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Answer::getParticipationId, participationId)
                .eq(Answer::getQuestionId, questionId)
                .eq(Answer::getIsDeleted, false);
        return count(queryWrapper) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAnswerStatus(Long id, Integer status) {
        return answerMapper.updateAnswerStatus(id, status) > 0;
    }

    @Override
    public int countUserCorrectAnswers(Long userId, Long contestId) {
        return answerMapper.countUserCorrectAnswers(userId, contestId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean calculateContestStatistics(Long contestId) {
        // 获取竞赛信息
        Contest contest = contestMapper.selectById(contestId);
        if (contest == null) {
            return false;
        }
        
        // 获取所有答题记录
        Page<UserAnswerVO> page = new Page<>(1, Integer.MAX_VALUE);
        IPage<UserAnswerVO> answerPage = answerMapper.pageContestAnswers(page, contestId, null, null, null);
        List<UserAnswerVO> answers = answerPage.getRecords();
        
        // 计算总分、平均分、最高分等统计信息
        // 实际项目中可以将这些统计信息保存到竞赛统计表中
        
        return true;
    }

    /**
     * 检查指定参赛记录是否已回答过指定题目
     * 
     * @param participationId 参赛记录ID
     * @param questionId 题目ID
     * @return 是否已回答
     */
    private boolean hasAnsweredByParticipationAndQuestion(Long participationId, Long questionId) {
        LambdaQueryWrapper<Answer> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Answer::getParticipationId, participationId)
                .eq(Answer::getQuestionId, questionId)
                .eq(Answer::getIsDeleted, false);
        return count(queryWrapper) > 0;
    }
} 